/**
 * Thinking in java 
 *  2018/08/01
 */
package com.dzb.nioclient;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;


/**
 * @author dzb
 * @date 2018年8月15日 下午12:49:50
 * @description  
 * @version 1.0.0
 */
public class BossThread extends Thread{
	
	private static ServerSocketChannel serverSocketChannel;

	public static Selector selector;

	/** 绑定服务端口，并且初始化一个selector */
	public BossThread(int port) {
		try {
			serverSocketChannel = ServerSocketChannel.open();
			serverSocketChannel.configureBlocking(false);
			// 开启并监听端口
			serverSocketChannel.bind(new InetSocketAddress(port));
			System.out.println("NIO启动:" + port);

			// 选择器，根据指定的条件，选择需要的东西
			// 获取一个选择器
			selector = Selector.open();
			// 在这个socket服务端通道上面，添加刚刚获取的选择器
			// 增加一个过滤条件：OP_ACCEPT 建立新的连接
			serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		} catch (IOException e) {
		}
	}
	
	/** 处理accept新建立的链接 */
	@Override
	public void run() {
		// serversocket
		try {
			while (true) {

				// 根据查询器已有的条件去查询(去操作系统底层管理socket连接的地方查询)
				int count = selector.select(100);
				if (count == 0) {
					continue;
				}

				// 获取查询结果
				Set<SelectionKey> selected = selector.selectedKeys();
				// 遍历查询结果
				Iterator<SelectionKey> iter = selected.iterator();
				while (iter.hasNext()) {
					// 被封装的查询结果
					SelectionKey key = iter.next();
					if (!key.isAcceptable()) {
						continue;
					}
					// 在服务端通道中，取出新的socket连接
					SocketChannel clientSocketChannel = serverSocketChannel.accept();
					// 设置为非阻塞模式
					clientSocketChannel.configureBlocking(false);
					
					// 随机或者其他方式，选择一个work线程去处理这个新连接
					int random = new Random().nextInt(3);
					WorkThread workThread = NioServers.workThreads[random];
					workThread.processSocketChannel(clientSocketChannel);
					System.out.println("有新的连接啦");
				}
				// 清除查询结果
				selected.clear();
				// 清除正在被处理的记录
				selector.selectNow();
			}

		} catch (Exception e) {
		}
	}
	

}
